package com.example.ercmssystem2.service.impl;

import com.example.ercmssystem2.entity.Department;
import com.example.ercmssystem2.entity.User;
import com.example.ercmssystem2.repository.DepartmentRepository;
import com.example.ercmssystem2.repository.UserRepository;
import com.example.ercmssystem2.service.DepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Transactional
public class DepartmentServiceImpl implements DepartmentService {

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public Department createDepartment(Department department, Long createdBy) {
        // 验证部门名称唯一性
        if (!isDepartmentNameUnique(department.getName(), null)) {
            throw new RuntimeException("部门名称已存在");
        }

        // 验证父部门是否存在
        if (department.getParentId() != null) {
            Optional<Department> parentDept = departmentRepository.findById(department.getParentId());
            if (parentDept.isEmpty() || !parentDept.get().getEnabled()) {
                throw new RuntimeException("父部门不存在或已禁用");
            }
        }

        // 验证部门管理员是否存在
        if (department.getManagerId() != null) {
            Optional<User> manager = userRepository.findById(department.getManagerId());
            if (manager.isEmpty() || !manager.get().getEnabled()) {
                throw new RuntimeException("部门管理员不存在或已禁用");
            }
        }

        department.setCreatedBy(createdBy);
        return departmentRepository.save(department);
    }

    @Override
    public Department updateDepartment(Long id, Department department) {
        Optional<Department> existingDept = departmentRepository.findById(id);
        if (existingDept.isEmpty()) {
            throw new RuntimeException("部门不存在");
        }

        Department existing = existingDept.get();
        
        // 验证部门名称唯一性（排除当前部门）
        if (!isDepartmentNameUnique(department.getName(), id)) {
            throw new RuntimeException("部门名称已存在");
        }

        // 验证父部门是否存在且不能是自己
        if (department.getParentId() != null) {
            if (department.getParentId().equals(id)) {
                throw new RuntimeException("父部门不能是自己");
            }
            Optional<Department> parentDept = departmentRepository.findById(department.getParentId());
            if (parentDept.isEmpty() || !parentDept.get().getEnabled()) {
                throw new RuntimeException("父部门不存在或已禁用");
            }
        }

        // 验证部门管理员是否存在
        if (department.getManagerId() != null) {
            Optional<User> manager = userRepository.findById(department.getManagerId());
            if (manager.isEmpty() || !manager.get().getEnabled()) {
                throw new RuntimeException("部门管理员不存在或已禁用");
            }
        }

        existing.setName(department.getName());
        existing.setDescription(department.getDescription());
        existing.setParentId(department.getParentId());
        existing.setManagerId(department.getManagerId());

        return departmentRepository.save(existing);
    }

    @Override
    public void deleteDepartment(Long id) {
        Optional<Department> department = departmentRepository.findById(id);
        if (department.isEmpty()) {
            throw new RuntimeException("部门不存在");
        }

        // 检查是否有子部门
        List<Department> children = departmentRepository.findByParentIdAndEnabledTrue(id);
        if (!children.isEmpty()) {
            throw new RuntimeException("请先删除子部门");
        }

        // 软删除
        Department dept = department.get();
        dept.setEnabled(false);
        departmentRepository.save(dept);
    }

    @Override
    public Department getDepartmentById(Long id) {
        Optional<Department> department = departmentRepository.findById(id);
        if (department.isEmpty() || !department.get().getEnabled()) {
            throw new RuntimeException("部门不存在或已禁用");
        }
        
        Department dept = department.get();
        enrichDepartmentInfo(dept);
        return dept;
    }

    @Override
    public List<Department> getAllDepartments() {
        List<Department> departments = departmentRepository.findByEnabledTrue();
        departments.forEach(this::enrichDepartmentInfo);
        return departments;
    }

    @Override
    public List<Department> findAllDepartments() {
        return getAllDepartments();
    }

    @Override
    public List<Department> getDepartmentTree() {
        List<Department> allDepartments = departmentRepository.findByEnabledTrue();
        
        // 获取所有用户信息用于填充管理员姓名
        Map<Long, String> userNames = userRepository.findAll().stream()
                .collect(Collectors.toMap(User::getId, User::getRealName));

        // 获取所有部门信息用于填充父部门姓名
        Map<Long, String> departmentNames = allDepartments.stream()
                .collect(Collectors.toMap(Department::getId, Department::getName));

        // 填充管理员姓名和父部门姓名
        allDepartments.forEach(dept -> {
            if (dept.getManagerId() != null) {
                dept.setManagerName(userNames.get(dept.getManagerId()));
            }
            if (dept.getParentId() != null) {
                dept.setParentName(departmentNames.get(dept.getParentId()));
            }
        });

        // 构建树结构
        Map<Long, List<Department>> parentChildMap = allDepartments.stream()
                .filter(dept -> dept.getParentId() != null)
                .collect(Collectors.groupingBy(Department::getParentId));

        allDepartments.forEach(dept -> dept.setChildren(parentChildMap.get(dept.getId())));

        return allDepartments.stream()
                .filter(dept -> dept.getParentId() == null)
                .collect(Collectors.toList());
    }

    @Override
    public List<Department> getTopLevelDepartments() {
        List<Department> departments = departmentRepository.findByParentIdIsNullAndEnabledTrue();
        departments.forEach(this::enrichDepartmentInfo);
        return departments;
    }

    @Override
    public List<Department> getChildDepartments(Long parentId) {
        List<Department> departments = departmentRepository.findByParentIdAndEnabledTrue(parentId);
        departments.forEach(this::enrichDepartmentInfo);
        return departments;
    }

    @Override
    public List<Department> getDepartmentsByManager(Long managerId) {
        List<Department> departments = departmentRepository.findByManagerIdAndEnabledTrue(managerId);
        departments.forEach(this::enrichDepartmentInfo);
        return departments;
    }

    @Override
    public Department setDepartmentManager(Long departmentId, Long managerId) {
        Optional<Department> department = departmentRepository.findById(departmentId);
        if (department.isEmpty() || !department.get().getEnabled()) {
            throw new RuntimeException("部门不存在或已禁用");
        }

        if (managerId != null) {
            Optional<User> manager = userRepository.findById(managerId);
            if (manager.isEmpty() || !manager.get().getEnabled()) {
                throw new RuntimeException("用户不存在或已禁用");
            }
        }

        Department dept = department.get();
        dept.setManagerId(managerId);
        return departmentRepository.save(dept);
    }

    @Override
    public boolean hasDepartmentPermission(Long userId, Long departmentId) {
        Optional<User> user = userRepository.findById(userId);
        if (user.isEmpty() || !user.get().getEnabled()) {
            return false;
        }

        User currentUser = user.get();
        
        // 系统管理员拥有所有权限
        if ("ADMIN".equals(currentUser.getRole())) {
            return true;
        }

        // 部门管理员检查
        if ("DEPT_MANAGER".equals(currentUser.getRole())) {
            List<Department> manageableDepts = getUserManageableDepartments(userId);
            return manageableDepts.stream().anyMatch(dept -> dept.getId().equals(departmentId));
        }

        return false;
    }

    @Override
    public List<Department> getUserManageableDepartments(Long userId) {
        Optional<User> user = userRepository.findById(userId);
        if (user.isEmpty() || !user.get().getEnabled()) {
            return new ArrayList<>();
        }

        User currentUser = user.get();
        
        // 系统管理员可以管理所有部门
        if ("ADMIN".equals(currentUser.getRole())) {
            return getAllDepartments();
        }

        // 部门管理员只能管理自己管理的部门及其子部门
        if ("DEPT_MANAGER".equals(currentUser.getRole())) {
            List<Department> managedDepts = departmentRepository.findByManagerIdAndEnabledTrue(userId);
            List<Department> allManageable = new ArrayList<>(managedDepts);
            
            // 添加所有子部门
            for (Department dept : managedDepts) {
                List<Department> children = departmentRepository.findAllChildrenRecursive(dept.getId());
                allManageable.addAll(children);
            }
            
            return allManageable;
        }

        return new ArrayList<>();
    }

    @Override
    public boolean isDepartmentNameUnique(String name, Long excludeId) {
        if (excludeId == null) {
            return !departmentRepository.findByNameAndEnabledTrue(name).isPresent();
        } else {
            return !departmentRepository.existsByNameAndEnabledTrueAndIdNot(name, excludeId);
        }
    }

    // 私有方法：丰富部门信息
    private void enrichDepartmentInfo(Department department) {
        if (department.getManagerId() != null) {
            Optional<User> manager = userRepository.findById(department.getManagerId());
            manager.ifPresent(user -> department.setManagerName(user.getRealName()));
        }
        
        if (department.getParentId() != null) {
            Optional<Department> parent = departmentRepository.findById(department.getParentId());
            parent.ifPresent(dept -> department.setParentName(dept.getName()));
        }
    }
} 